// onjava/CollectionMethodDifferences.java
// (c)2021 MindView LLC: see Copyright.txt
// We make no guarantees that this code is fit for any purpose.
// Visit http://OnJava8.com for more book information.
// {java onjava.CollectionMethodDifferences}
package onjava;

import java.lang.reflect.*;
import java.util.*;
import java.util.stream.*;

/**
 * 
 * 泛型方法 -> Set实用工具: 各种Collection和Map类之间的区别
 *
 * @author Lucky Yang
 */
public class CollectionMethodDifferences {
  static Set<String> methodSet(Class<?> type) {
    return Arrays.stream(type.getMethods())
        .map(Method::getName)
        .collect(Collectors.toCollection(TreeSet::new));
  }

  static void interfaces(Class<?> type) {
    System.out.print("Interfaces in " +
        type.getSimpleName() + ": ");
    System.out.println(
        Arrays.stream(type.getInterfaces())
            .map(Class::getSimpleName)
            .collect(Collectors.toList()));
  }

  static Set<String> object = methodSet(Object.class);
  static {
    object.add("clone");
  }

  static void difference(Class<?> superset, Class<?> subset) {
    System.out.print(superset.getSimpleName() +
        " extends " + subset.getSimpleName() +
        ", adds: ");
    Set<String> comp = Sets.difference(
        methodSet(superset), methodSet(subset));
    // Ignore 'Object' methods
    comp.removeAll(object); 
    System.out.println(comp);
    interfaces(superset);
  }

  public static void main(String[] args) {
    System.out.println("Collection: " +
        methodSet(Collection.class));
    interfaces(Collection.class);
    difference(Set.class, Collection.class);
    difference(HashSet.class, Set.class);
    difference(LinkedHashSet.class, HashSet.class);
    difference(TreeSet.class, Set.class);
    difference(List.class, Collection.class);
    difference(ArrayList.class, List.class);
    difference(LinkedList.class, List.class);
    difference(Queue.class, Collection.class);
    difference(PriorityQueue.class, Queue.class);
    System.out.println("Map: " + methodSet(Map.class));
    difference(HashMap.class, Map.class);
    difference(LinkedHashMap.class, HashMap.class);
    difference(SortedMap.class, Map.class);
    difference(TreeMap.class, Map.class);
  }
}
/*
 * Output:
 * Collection: [add, addAll, clear, contains, containsAll,
 * equals, forEach, hashCode, isEmpty, iterator,
 * parallelStream, remove, removeAll, removeIf, retainAll,
 * size, spliterator, stream, toArray]
 * Interfaces in Collection: [Iterable]
 * Set extends Collection, adds: []
 * Interfaces in Set: [Collection]
 * HashSet extends Set, adds: []
 * Interfaces in HashSet: [Set, Cloneable, Serializable]
 * LinkedHashSet extends HashSet, adds: []
 * Interfaces in LinkedHashSet: [Set, Cloneable,
 * Serializable]
 * TreeSet extends Set, adds: [headSet,
 * descendingIterator, descendingSet, pollLast, subSet,
 * floor, tailSet, ceiling, last, lower, comparator,
 * pollFirst, first, higher]
 * Interfaces in TreeSet: [NavigableSet, Cloneable,
 * Serializable]
 * List extends Collection, adds: [replaceAll, get,
 * indexOf, subList, set, sort, lastIndexOf, listIterator]
 * Interfaces in List: [Collection]
 * ArrayList extends List, adds: [trimToSize,
 * ensureCapacity]
 * Interfaces in ArrayList: [List, RandomAccess,
 * Cloneable, Serializable]
 * LinkedList extends List, adds: [offerFirst, poll,
 * getLast, offer, getFirst, removeFirst, element,
 * removeLastOccurrence, peekFirst, peekLast, push,
 * pollFirst, removeFirstOccurrence, descendingIterator,
 * pollLast, removeLast, pop, addLast, peek, offerLast,
 * addFirst]
 * Interfaces in LinkedList: [List, Deque, Cloneable,
 * Serializable]
 * Queue extends Collection, adds: [poll, peek, offer,
 * element]
 * Interfaces in Queue: [Collection]
 * PriorityQueue extends Queue, adds: [comparator]
 * Interfaces in PriorityQueue: [Serializable]
 * Map: [clear, compute, computeIfAbsent,
 * computeIfPresent, containsKey, containsValue, entrySet,
 * equals, forEach, get, getOrDefault, hashCode, isEmpty,
 * keySet, merge, put, putAll, putIfAbsent, remove,
 * replace, replaceAll, size, values]
 * HashMap extends Map, adds: []
 * Interfaces in HashMap: [Map, Cloneable, Serializable]
 * LinkedHashMap extends HashMap, adds: []
 * Interfaces in LinkedHashMap: [Map]
 * SortedMap extends Map, adds: [lastKey, subMap,
 * comparator, firstKey, headMap, tailMap]
 * Interfaces in SortedMap: [Map]
 * TreeMap extends Map, adds: [descendingKeySet,
 * navigableKeySet, higherEntry, higherKey, floorKey,
 * subMap, ceilingKey, pollLastEntry, firstKey, lowerKey,
 * headMap, tailMap, lowerEntry, ceilingEntry,
 * descendingMap, pollFirstEntry, lastKey, firstEntry,
 * floorEntry, comparator, lastEntry]
 * Interfaces in TreeMap: [NavigableMap, Cloneable,
 * Serializable]
 */
